﻿using System;
using System.Linq;
using System.Windows.Forms;
using S7.Net;
using S7PlcDataCollector.Models;
using S7PlcDataCollector.Service;
using ZbSkin.Frm;

namespace S7PlcDataCollector.Client.Forms
{
    public partial class FrmPlcDeviceSetup : PopupForm
    {
        private readonly bool _addFlag;
        private readonly S7PlcEntity _model;
        private S7PlcEntity _oldModel;

        private static readonly string DataType = "PLC设备";

        public FrmPlcDeviceSetup()
            : this(true, new S7PlcEntity())
        {
        }

        public FrmPlcDeviceSetup(S7PlcEntity model)
            : this(false, model)
        {
        }

        private FrmPlcDeviceSetup(bool addFlag, S7PlcEntity model)
        {
            InitializeComponent();
            _addFlag = addFlag;
            _model = model;
        }

        private void FrmPlcDeviceSetup_Load(object sender, EventArgs e)
        {
            var plcTypeList = S7PlcDataCollectorService.Instance.SupportedPlcTypeList;
            cmbPlcType.DataSource = plcTypeList;

            if (!_addFlag && _model != null)
            {
                _oldModel = _model.CloneEntity();

                textBoxIp.Text = _model.Ip;
                textBoxPort.Text = _model.Port.ToString();
                textBoxRack.Text = _model.Rack.ToString();
                textBoxSlot.Text = _model.Slot.ToString();

                var type = Enum.IsDefined(typeof(CpuType), _model.Type)
                    ? (CpuType) _model.Type
                    : CpuType.S7200;
                cmbPlcType.SelectedItem = type;

                ////使用LINQ获取查询结果的索引
                //var deviceTypeId = _model?.DeviceTypeId ?? 0;
                //var deviceTypeItem = deviceTypeList.Select((deviceType, index) => new { index, deviceType })
                //    .Where(t => t.deviceType.Id == deviceTypeId)
                //    .OrderBy(t => t.deviceType).FirstOrDefault();
                //comboBoxDeviceType.SelectedIndex = deviceTypeItem?.index ?? 0;
            }

            if (_addFlag)
            {
                textBoxPort.Text = S7PlcDataCollectorService.S7PlcDefaultPort.ToString();
            }

            textBoxIp.Focus();
            textBoxIp.SelectionStart = textBoxIp.TextLength;

            FrmTitle = _addFlag ? $"添加{DataType}" : $"编辑{DataType}";
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            if (!CheckParas())
            {
                return;
            }

            var models = S7PlcDataCollectorService.Instance.GetS7PlcEntityList();
            var model = models.FirstOrDefault(t => _model.Ip.Equals(t.Ip) && _model.Port == t.Port);

            if (_addFlag)
            {
                AddPlcDevice(model);
            }
            else
            {
                UpdatePlcDevice(model);
            }
        }

        private void tnCancel_Click(object sender, EventArgs e)
        {
            Close();
        }

        private bool CheckParas()
        {
            var ip = textBoxIp.Text.Trim();
            if (string.IsNullOrWhiteSpace(ip))
            {
                MessageBoxEx.Warning($"请输入{DataType}IP地址", this);
                return false;
            }

            var portStr = textBoxPort.Text.Trim();
            if (string.IsNullOrWhiteSpace(portStr))
            {
                MessageBoxEx.Warning($"请输入{DataType}端口", this);
                return false;
            }

            int port;
            if (!int.TryParse(portStr, out port) || port <= 0)
            {
                MessageBoxEx.Warning($"{DataType}端口不合法", this);
                return false;
            }

            var rackStr = textBoxRack.Text.Trim();
            if (string.IsNullOrWhiteSpace(rackStr))
            {
                MessageBoxEx.Warning($"请输入{DataType}Rack", this);
                return false;
            }

            short rack;
            if (!short.TryParse(rackStr, out rack) || rack < 0)
            {
                MessageBoxEx.Warning($@"{DataType}Rack不合法", this);
                return false;
            }

            var slotStr = textBoxSlot.Text.Trim();
            if (string.IsNullOrWhiteSpace(slotStr))
            {
                MessageBoxEx.Warning($@"请输入{DataType}Slot", this);
                return false;
            }

            short slot;
            if (!short.TryParse(slotStr, out slot) || slot < 0)
            {
                MessageBoxEx.Warning($@"{DataType}Slot不合法", this);
                return false;
            }

            _model.Type = (int) (CpuType) cmbPlcType.SelectedItem;
            _model.Ip = ip;
            _model.Port = port;
            _model.Rack = rack;
            _model.Slot = slot;
            return true;
        }

        private void AddPlcDevice(S7PlcEntity model)
        {
            if (model != null)
            {
                MessageBoxEx.Warning($"{DataType}已存在", this);
                return;
            }

            _model.Rid = S7PlcDataCollectorService.Instance.AddS7PlcEntity(_model);
            if (_model.Rid > 0)
            {
                S7PlcDataCollectorService.Instance.AddPlcLink(_model);
                DialogResult = DialogResult.OK;
            }
            else
            {
                MessageBoxEx.Warning($"添加{DataType}失败", this);
            }
        }

        private void UpdatePlcDevice(S7PlcEntity model)
        {
            if (model != null && model.Rid != _model.Rid)
            {
                MessageBoxEx.Warning($"{DataType}已存在", this);
                return;
            }

            if (S7PlcDataCollectorService.Instance.UpdateS7PlcEntity(_model))
            {
                S7PlcDataCollectorService.Instance.RemovePlcLink(_oldModel);
                S7PlcDataCollectorService.Instance.AddPlcLink(_model);
                DialogResult = DialogResult.OK;
            }
            else
            {
                MessageBoxEx.Warning($"修改{DataType}失败", this);
            }
        }
    }
}
